<!DOCTYPE html>
<html lang="zh-CN">
    <head>
    <meta charset="utf-8">

    

    <!-- 渲染优化 -->
    <meta name="renderer" content="webkit">
    <meta name="force-rendering" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="HandheldFriendly" content="True" >
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <!--icon-->

    
        <link rel="shortcut icon" href="https://s1.imgpp.com/2022/01/28/owl.png">
    
    
    
    
    


    <!-- meta -->


<title>Spring | 猫头鹰的BLOG</title>


    <meta name="keywords" content="Spring, 猫头鹰的博客">




    <!-- OpenGraph -->
 
    <meta name="description" content="Spring 框架两大核心机制（IoC、AOP） IoC（控制反转）&#x2F; DI（依赖注入） AOP（面向切面编程）  Spring 是一个企业级开发框架，是软件设计层面的框架，优势在于可以将应用程序进行分层，开发者可以自主选择组件。 MVC：Struts2、Spring MVC ORMapping：Hibernate、MyBatis、Spring Data 如何使用 IoC 创建 Maven 工程，">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring">
<meta property="og:url" content="http://example.com/2022/04/07/Spring%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="猫头鹰的BLOG">
<meta property="og:description" content="Spring 框架两大核心机制（IoC、AOP） IoC（控制反转）&#x2F; DI（依赖注入） AOP（面向切面编程）  Spring 是一个企业级开发框架，是软件设计层面的框架，优势在于可以将应用程序进行分层，开发者可以自主选择组件。 MVC：Struts2、Spring MVC ORMapping：Hibernate、MyBatis、Spring Data 如何使用 IoC 创建 Maven 工程，">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://images.pexels.com/photos/142497/pexels-photo-142497.jpeg?cs=srgb&dl=pexels-mali-maeder-142497.jpg&fm=jpg">
<meta property="article:published_time" content="2022-04-07T02:00:20.000Z">
<meta property="article:modified_time" content="2022-04-09T11:32:45.625Z">
<meta property="article:author" content="张程">
<meta property="article:tag" content="Spring">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://images.pexels.com/photos/142497/pexels-photo-142497.jpeg?cs=srgb&dl=pexels-mali-maeder-142497.jpg&fm=jpg">


    
<link rel="stylesheet" href="/css/style/main.css">
 

    
    
    
        <link rel="stylesheet" id="hl-default-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/arduino-light.min.css" media="none" >
        
            <link rel="stylesheet" id="hl-dark-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/obsidian.min.css" media="none">
        
    

    

    
    
<link rel="stylesheet" href="/css/style/dark.css">

    
<script src="/js/darkmode.js"></script>



     
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
 

    <!-- custom head -->

<meta name="generator" content="Hexo 6.0.0"></head>

    <body>
        <div id="app">
            <header class="header">
    <div class="header__left">
        <a href="/" class="button">
            <span class="logo__text">猫头鹰</span>
        </a>
    </div>
    <div class="header__right">
        
            <div class="navbar__menus">
                
                    <a href="/" class="navbar-menu button">首页</a>
                
                    <a href="/tags/" class="navbar-menu button">标签</a>
                
                    <a href="/categories/" class="navbar-menu button">分类</a>
                
                    <a href="/archives/" class="navbar-menu button">归档</a>
                
            </div>
        
        
        
    <a href="/search/" id="btn-search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="24" height="24" fill="currentColor" stroke="currentColor" stroke-width="32"><path d="M192 448c0-141.152 114.848-256 256-256s256 114.848 256 256-114.848 256-256 256-256-114.848-256-256z m710.624 409.376l-206.88-206.88A318.784 318.784 0 0 0 768 448c0-176.736-143.264-320-320-320S128 271.264 128 448s143.264 320 320 320a318.784 318.784 0 0 0 202.496-72.256l206.88 206.88 45.248-45.248z"></path></svg>
    </a>


        
        
    <a href="javaScript:void(0);" id="btn-toggle-dark">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
    </a>


        
            <a class="dropdown-icon button" id="btn-dropdown" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width='24' height='24' fill="none" stroke="currentColor" stroke-width="0.7" stroke-linecap="round" stroke-linejoin="round"><path fill="currentColor" d="M3.314,4.8h13.372c0.41,0,0.743-0.333,0.743-0.743c0-0.41-0.333-0.743-0.743-0.743H3.314c-0.41,0-0.743,0.333-0.743,0.743C2.571,4.467,2.904,4.8,3.314,4.8z M16.686,15.2H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,15.2,16.686,15.2z M16.686,9.257H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,9.257,16.686,9.257z"></path></svg></a>
            <div class="dropdown-menus" id="dropdown-menus">
                
                    <a href="/" class="dropdown-menu button">首页</a>
                
                    <a href="/tags/" class="dropdown-menu button">标签</a>
                
                    <a href="/categories/" class="dropdown-menu button">分类</a>
                
                    <a href="/archives/" class="dropdown-menu button">归档</a>
                
            </div>
        
    </div>
</header>


            <main class="main">
    

<div class="post-title">
    <h1 class="post-title__text">
        Spring
    </h1>
    <div class="post-title__meta">
        <a href="/archives/2022/04/" class="post-meta__date button">2022-04-07</a>
        
    <span class="separate-dot"></span><a href="/categories/Spring/" class="button">Spring</a>

 
        
    
     
    <span id="busuanzi_container_page_pv" hidden>
        <span class="separate-dot"></span>
        <span></span>
        <span id="busuanzi_value_page_pv"></span>
        <span>次观看</span>
    </span>



 

 
    </div>
</div>



<article class="post content-card">
    <div class="post__header">
    
        <div class="post-thumbnail lazy" data-bg="https://images.pexels.com/photos/142497/pexels-photo-142497.jpeg?cs=srgb&amp;dl=pexels-mali-maeder-142497.jpg&amp;fm=jpg"></div>
    
</div>
    <div class="post__content">
        <h3 id="Spring-框架两大核心机制（IoC、AOP）"><a href="#Spring-框架两大核心机制（IoC、AOP）" class="headerlink" title="Spring 框架两大核心机制（IoC、AOP）"></a>Spring 框架两大核心机制（IoC、AOP）</h3><ul>
<li>IoC（控制反转）/ DI（依赖注入）</li>
<li>AOP（面向切面编程）</li>
</ul>
<p>Spring 是一个企业级开发框架，是软件设计层面的框架，优势在于可以将应用程序进行分层，开发者可以自主选择组件。</p>
<p>MVC：Struts2、Spring MVC</p>
<p>ORMapping：Hibernate、MyBatis、Spring Data</p>
<h3 id="如何使用-IoC"><a href="#如何使用-IoC" class="headerlink" title="如何使用 IoC"></a>如何使用 IoC</h3><ul>
<li>创建 Maven 工程，pom.xml 添加依赖</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">project</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://maven.apache.org/POM/4.0.0&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="hljs-attr">xsi:schemalocation</span>=<span class="hljs-string">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">modelversion</span>&gt;</span>4.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">modelversion</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">groupid</span>&gt;</span>com.southwind<span class="hljs-tag">&lt;/<span class="hljs-name">groupid</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactid</span>&gt;</span>aispringioc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactid</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">groupid</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupid</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactid</span>&gt;</span>spring-context<span class="hljs-tag">&lt;/<span class="hljs-name">artifactid</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.11.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span></code></pre>

<ul>
<li>创建实体类 Student</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> </span>&#123;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">long</span> id;
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;
&#125;</code></pre>

<ul>
<li>传统的开发方式，手动 new Student</li>
</ul>
<pre><code class="hljs java">Student student = <span class="hljs-keyword">new</span> Student();
student.setId(<span class="hljs-number">1L</span>);
student.setName(<span class="hljs-string">&quot;张三&quot;</span>);
student.setAge(<span class="hljs-number">22</span>);
System.out.println(student);</code></pre>

<ul>
<li>通过 IoC 创建对象，在配置文件中添加需要管理的对象，XML 格式的配置文件，文件名可以自定义。</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span> <span class="hljs-attr">xmlns:p</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/p&quot;</span> <span class="hljs-attr">xsi:schemalocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">&quot;</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;张三&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;age&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;22&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span></code></pre>

<ul>
<li>从 IoC 中获取对象，通过 id 获取。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-comment">//加载配置文件</span>
ApplicationContext applicationContext = <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">&quot;spring.xml&quot;</span>);
Student student = (Student) applicationContext.getBean(<span class="hljs-string">&quot;student&quot;</span>);
System.out.println(student);</code></pre>

<h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><ul>
<li><p>通过配置 <code>bean</code> 标签来完成对象的管理。</p>
<ul>
<li><p><code>id</code>：对象名。</p>
</li>
<li><p><code>class</code>：对象的模版类（所有交给 IoC 容器来管理的类必须有无参构造函数，因为 Spring 底层是通过反射机制来创建对象，调用的是无参构造）</p>
</li>
</ul>
</li>
<li><p>对象的成员变量通过 <code>property</code> 标签完成赋值。</p>
<ul>
<li><code>name</code>：成员变量名。</li>
<li><code>value</code>：成员变量值（基本数据类型，String 可以直接赋值，如果是其他引用类型，不能通过 value 赋值）</li>
<li><code>ref</code>：将 IoC 中的另外一个 bean 赋给当前的成员变量（DI）</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;张三&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;age&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;22&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;科技路&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

</li>
</ul>
<h3 id="IoC-底层原理"><a href="#IoC-底层原理" class="headerlink" title="IoC 底层原理"></a>IoC 底层原理</h3><ul>
<li>读取配置文件，解析 XML。</li>
<li>通过反射机制实例化配置文件中所配置所有的 bean。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.ioc;
 
<span class="hljs-keyword">import</span> org.dom4j.Document;
<span class="hljs-keyword">import</span> org.dom4j.DocumentException;
<span class="hljs-keyword">import</span> org.dom4j.Element;
<span class="hljs-keyword">import</span> org.dom4j.io.SAXReader;
 
<span class="hljs-keyword">import</span> java.lang.reflect.Constructor;
<span class="hljs-keyword">import</span> java.lang.reflect.Field;
<span class="hljs-keyword">import</span> java.lang.reflect.InvocationTargetException;
<span class="hljs-keyword">import</span> java.lang.reflect.Method;
<span class="hljs-keyword">import</span> java.util.HashMap;
<span class="hljs-keyword">import</span> java.util.Iterator;
<span class="hljs-keyword">import</span> java.util.Map;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassPathXmlApplicationContext</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ApplicationContext</span> </span>&#123;
    <span class="hljs-keyword">private</span> Map&lt;string,object&gt; ioc = <span class="hljs-keyword">new</span> HashMap&lt;string, object=<span class="hljs-string">&quot;&quot;</span>&gt;();
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ClassPathXmlApplicationContext</span><span class="hljs-params">(String path)</span></span>&#123;
        <span class="hljs-keyword">try</span> &#123;
            SAXReader reader = <span class="hljs-keyword">new</span> SAXReader();
            Document document = reader.read(<span class="hljs-string">&quot;./src/main/resources/&quot;</span>+path);
            Element root = document.getRootElement();
            Iterator&lt;element&gt; iterator = root.elementIterator();
            <span class="hljs-keyword">while</span>(iterator.hasNext())&#123;
                Element element = iterator.next();
                String id = element.attributeValue(<span class="hljs-string">&quot;id&quot;</span>);
                String className = element.attributeValue(<span class="hljs-string">&quot;class&quot;</span>);
                <span class="hljs-comment">//通过反射机制创建对象</span>
                Class clazz = Class.forName(className);
                <span class="hljs-comment">//获取无参构造函数，创建目标对象</span>
                Constructor constructor = clazz.getConstructor();
                Object object = constructor.newInstance();
                <span class="hljs-comment">//给目标对象赋值</span>
                Iterator&lt;element&gt; beanIter = element.elementIterator();
                <span class="hljs-keyword">while</span>(beanIter.hasNext())&#123;
                    Element property = beanIter.next();
                    String name = property.attributeValue(<span class="hljs-string">&quot;name&quot;</span>);
                    String valueStr = property.attributeValue(<span class="hljs-string">&quot;value&quot;</span>);
                    String ref = property.attributeValue(<span class="hljs-string">&quot;ref&quot;</span>);
                    <span class="hljs-keyword">if</span>(ref == <span class="hljs-keyword">null</span>)&#123;
                        String methodName = <span class="hljs-string">&quot;set&quot;</span>+name.substring(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>).toUpperCase()+name.substring(<span class="hljs-number">1</span>);
                        Field field = clazz.getDeclaredField(name);
                        Method method = clazz.getDeclaredMethod(methodName,field.getType());
                        <span class="hljs-comment">//根据成员变量的数据类型将 value 进行转换</span>
                        Object value = <span class="hljs-keyword">null</span>;
                        <span class="hljs-keyword">if</span>(field.getType().getName() == <span class="hljs-string">&quot;long&quot;</span>)&#123;
                            value = Long.parseLong(valueStr);
                        &#125;
                        <span class="hljs-keyword">if</span>(field.getType().getName() == <span class="hljs-string">&quot;java.lang.String&quot;</span>)&#123;
                            value = valueStr;
                        &#125;
                        <span class="hljs-keyword">if</span>(field.getType().getName() == <span class="hljs-string">&quot;int&quot;</span>)&#123;
                            value = Integer.parseInt(valueStr);
                        &#125;
                        method.invoke(object,value);
                    &#125;
                    ioc.put(id,object);
                &#125;
            &#125;
        &#125; <span class="hljs-keyword">catch</span> (DocumentException e) &#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (ClassNotFoundException e)&#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (NoSuchMethodException e)&#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (InstantiationException e)&#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (IllegalAccessException e)&#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (InvocationTargetException e)&#123;
            e.printStackTrace();
        &#125; <span class="hljs-keyword">catch</span> (NoSuchFieldException e)&#123;
            e.printStackTrace();
        &#125;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getBean</span><span class="hljs-params">(String id)</span> </span>&#123;
        <span class="hljs-keyword">return</span> ioc.get(id);
    &#125;
&#125;</code></pre>

<h3 id="通过运行时类获取-bean"><a href="#通过运行时类获取-bean" class="headerlink" title="通过运行时类获取 bean"></a>通过运行时类获取 bean</h3><pre><code class="hljs java">ApplicationContext applicationContext = <span class="hljs-keyword">new</span> ClassPathXmlApplicationContext(<span class="hljs-string">&quot;spring.xml&quot;</span>);
Student student = (Student) applicationContext.getBean(Student.class);
System.out.println(student);</code></pre>

<p>这种方式存在一个问题，配置文件中一个数据类型的对象只能有一个实例，否则会抛出异常，因为没有唯一的 bean。</p>
<h3 id="通过有参构造创建-bean"><a href="#通过有参构造创建-bean" class="headerlink" title="通过有参构造创建 bean"></a>通过有参构造创建 bean</h3><ul>
<li>在实体类中创建对应的有参构造函数。</li>
<li>配置文件</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student3&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;3&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;小明&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;age&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;18&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student3&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">index</span>=<span class="hljs-string">&quot;0&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;3&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">index</span>=<span class="hljs-string">&quot;2&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;18&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">index</span>=<span class="hljs-string">&quot;1&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;小明&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">index</span>=<span class="hljs-string">&quot;3&quot;</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<h3 id="给-bean-注入集合"><a href="#给-bean-注入集合" class="headerlink" title="给 bean 注入集合"></a>给 bean 注入集合</h3><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;李四&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;age&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;33&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;addresses&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">list</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ref</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">&quot;address2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ref</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">list</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;科技路&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address2&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;高新区&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<h3 id="scope-作用域"><a href="#scope-作用域" class="headerlink" title="scope 作用域"></a>scope 作用域</h3><p>Spring 管理的 bean 是根据 scope 来生成的，表示 bean 的作用域，共4种，默认值是 singleton。</p>
<ul>
<li>singleton：单例，表示通过 IoC 容器获取的 bean 是唯一的。</li>
<li>prototype：原型，表示通过 IoC 容器获取的 bean 是不同的。</li>
<li>request：请求，表示在一次 HTTP 请求内有效。</li>
<li>session：回话，表示在一个用户会话内有效。</li>
</ul>
<p>request 和 session 只适用于 Web 项目，大多数情况下，使用单例和原型较多。</p>
<p>prototype 模式当业务代码获取 IoC 容器中的 bean 时，Spring 才去调用无参构造创建对应的 bean。</p>
<p>singleton 模式无论业务代码是否获取 IoC 容器中的 bean，Spring 在加载 spring.xml 时就会创建 bean。</p>
<h3 id="Spring-的继承"><a href="#Spring-的继承" class="headerlink" title="Spring 的继承"></a>Spring 的继承</h3><p>与 Java 的继承不同，Java 是类层面的继承，子类可以继承父类的内部结构信息；Spring 是对象层面的继承，子对象可以继承父对象的属性值。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student2&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;张三&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;age&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;22&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;addresses&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">list</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ref</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ref</span> <span class="hljs-attr">bean</span>=<span class="hljs-string">&quot;address2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ref</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">list</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;科技路&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address2&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;高新区&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;stu&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span> <span class="hljs-attr">parent</span>=<span class="hljs-string">&quot;student2&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;李四&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<p>Spring 的继承关注点在于具体的对象，而不在于类，即不同的两个类的实例化对象可以完成继承，前提是子对象必须包含父对象的所有属性，同时可以在此基础上添加其他的属性。</p>
<h3 id="Spring-的依赖"><a href="#Spring-的依赖" class="headerlink" title="Spring 的依赖"></a>Spring 的依赖</h3><p>与继承类似，依赖也是描述 bean 和 bean 之间的一种关系，配置依赖之后，被依赖的 bean 一定先创建，再创建依赖的 bean，A 依赖于 B，先创建 B，再创建 A。</p>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="hljs-attr">xsi:schemalocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">                           &quot;</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span> <span class="hljs-attr">depends-on</span>=<span class="hljs-string">&quot;user&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;user&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.User&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span></code></pre>

<h3 id="Spring-的-p-命名空间"><a href="#Spring-的-p-命名空间" class="headerlink" title="Spring 的 p 命名空间"></a>Spring 的 p 命名空间</h3><p>p 命名空间是对 IoC / DI 的简化操作，使用 p 命名空间可以更加方便的完成 bean 的配置以及 bean 之间的依赖注入。</p>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span> <span class="hljs-attr">xmlns:p</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/p&quot;</span> <span class="hljs-attr">xsi:schemalocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">&quot;</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;student&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Student&quot;</span> <span class="hljs-attr">p:id</span>=<span class="hljs-string">&quot;1&quot;</span> <span class="hljs-attr">p:name</span>=<span class="hljs-string">&quot;张三&quot;</span> <span class="hljs-attr">p:age</span>=<span class="hljs-string">&quot;22&quot;</span> <span class="hljs-attr">p:address-ref</span>=<span class="hljs-string">&quot;address&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;address&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Address&quot;</span> <span class="hljs-attr">p:id</span>=<span class="hljs-string">&quot;2&quot;</span> <span class="hljs-attr">p:name</span>=<span class="hljs-string">&quot;科技路&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span></code></pre>

<h3 id="Spring-的工厂方法"><a href="#Spring-的工厂方法" class="headerlink" title="Spring 的工厂方法"></a>Spring 的工厂方法</h3><p>IoC 通过工厂模式创建 bean 的方式有两种：</p>
<ul>
<li>静态工厂方法</li>
<li>实例工厂方法</li>
</ul>
<blockquote>
<p>静态工厂方法</p>
</blockquote>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.AllArgsConstructor;
<span class="hljs-keyword">import</span> lombok.Data;
<span class="hljs-keyword">import</span> lombok.NoArgsConstructor;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-meta">@AllArgsConstructor</span>
<span class="hljs-meta">@NoArgsConstructor</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> </span>&#123;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">long</span> id;
    <span class="hljs-keyword">private</span> String name;
&#125;</code></pre>

<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.factory;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Car;
 
<span class="hljs-keyword">import</span> java.util.HashMap;
<span class="hljs-keyword">import</span> java.util.Map;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StaticCarFactory</span> </span>&#123;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Map&lt;<span class="hljs-keyword">long</span>, car=<span class="hljs-string">&quot;&quot;</span>&gt; carMap;
    <span class="hljs-keyword">static</span>&#123;
        carMap = <span class="hljs-keyword">new</span> HashMap&lt;<span class="hljs-keyword">long</span>, car=<span class="hljs-string">&quot;&quot;</span>&gt;();
        carMap.put(<span class="hljs-number">1L</span>,<span class="hljs-keyword">new</span> Car(<span class="hljs-number">1L</span>,<span class="hljs-string">&quot;宝马&quot;</span>));
        carMap.put(<span class="hljs-number">2L</span>,<span class="hljs-keyword">new</span> Car(<span class="hljs-number">2L</span>,<span class="hljs-string">&quot;奔驰&quot;</span>));
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Car <span class="hljs-title">getCar</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span></span>&#123;
        <span class="hljs-keyword">return</span> carMap.get(id);
    &#125;
&#125;</code></pre>

<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- 配置静态工厂创建 Car --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;car&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.factory.StaticCarFactory&quot;</span> <span class="hljs-attr">factory-method</span>=<span class="hljs-string">&quot;getCar&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<blockquote>
<p>实例工厂方法</p>
</blockquote>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.factory;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Car;
 
<span class="hljs-keyword">import</span> java.util.HashMap;
<span class="hljs-keyword">import</span> java.util.Map;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InstanceCarFactory</span> </span>&#123;
    <span class="hljs-keyword">private</span> Map&lt;<span class="hljs-keyword">long</span>, car=<span class="hljs-string">&quot;&quot;</span>&gt; carMap;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InstanceCarFactory</span><span class="hljs-params">()</span></span>&#123;
        carMap = <span class="hljs-keyword">new</span> HashMap&lt;<span class="hljs-keyword">long</span>, car=<span class="hljs-string">&quot;&quot;</span>&gt;();
        carMap.put(<span class="hljs-number">1L</span>,<span class="hljs-keyword">new</span> Car(<span class="hljs-number">1L</span>,<span class="hljs-string">&quot;宝马&quot;</span>));
        carMap.put(<span class="hljs-number">2L</span>,<span class="hljs-keyword">new</span> Car(<span class="hljs-number">2L</span>,<span class="hljs-string">&quot;奔驰&quot;</span>));
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> Car <span class="hljs-title">getCar</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span></span>&#123;
        <span class="hljs-keyword">return</span> carMap.get(id);
    &#125;
&#125;</code></pre>

<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- 配置实例工厂 bean --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;carFactory&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.factory.InstanceCarFactory&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-comment">&lt;!-- 赔偿实例工厂创建 Car --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;car2&quot;</span> <span class="hljs-attr">factory-bean</span>=<span class="hljs-string">&quot;carFactory&quot;</span> <span class="hljs-attr">factory-method</span>=<span class="hljs-string">&quot;getCar&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<h3 id="IoC-自动装载（Autowire）"><a href="#IoC-自动装载（Autowire）" class="headerlink" title="IoC 自动装载（Autowire）"></a>IoC 自动装载（Autowire）</h3><p>IoC 负责创建对象，DI 负责完成对象的依赖注入，通过配置 property 标签的 ref 属性来完成，同时 Spring 提供了另外一种更加简便的依赖注入方式：自动装载，不需要手动配置 property，IoC 容器会自动选择 bean 完成注入。</p>
<p>自动装载有两种方式：</p>
<ul>
<li>byName：通过属性名自动装载</li>
<li>byType：通过属性的数据类型自动装载</li>
</ul>
<blockquote>
<p>byName</p>
</blockquote>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;cars&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Car&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;1&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;宝马&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;person&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Person&quot;</span> <span class="hljs-attr">autowire</span>=<span class="hljs-string">&quot;byName&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;11&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;张三&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<blockquote>
<p>byType</p>
</blockquote>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;car&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Car&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;2&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;奔驰&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;person&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.entity.Person&quot;</span> <span class="hljs-attr">autowire</span>=<span class="hljs-string">&quot;byType&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;id&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;11&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;name&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;张三&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<p>byType 需要注意，如果同时存在两个及以上的符合条件的 bean 时，自动装载会抛出异常。</p>
<h3 id="AOP"><a href="#AOP" class="headerlink" title="AOP"></a>AOP</h3><p>AOP：Aspect Oriented Programming 面向切面编程。</p>
<p>AOP 的优点：</p>
<ul>
<li>降低模块之间的耦合度。</li>
<li>使系统更容易扩展。</li>
<li>更好的代码复用。</li>
<li>非业务代码更加集中，不分散，便于统一管理。</li>
<li>业务代码更加简洁存粹，不参杂其他代码的影响。</li>
</ul>
<p>AOP 是对面向对象编程的一个补充，在运行时，动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面编程。将不同方法的同一个位置抽象成一个切面对象，对该切面对象进行编程就是 AOP。</p>
<h3 id="如何使用？"><a href="#如何使用？" class="headerlink" title="如何使用？"></a>如何使用？</h3><ul>
<li>创建 Maven 工程，pom.xml 添加</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupid</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactid</span>&gt;</span>spring-context<span class="hljs-tag">&lt;/<span class="hljs-name">artifactid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.11.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
     
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupid</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactid</span>&gt;</span>spring-aop<span class="hljs-tag">&lt;/<span class="hljs-name">artifactid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.11.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupid</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactid</span>&gt;</span>spring-aspects<span class="hljs-tag">&lt;/<span class="hljs-name">artifactid</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.11.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span></code></pre>

<ul>
<li>创建一个计算器接口 Cal，定义4个方法。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.utils;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Cal</span> </span>&#123;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1,<span class="hljs-keyword">int</span> num2)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sub</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1,<span class="hljs-keyword">int</span> num2)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">mul</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1,<span class="hljs-keyword">int</span> num2)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">div</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1,<span class="hljs-keyword">int</span> num2)</span></span>;
&#125;</code></pre>

<ul>
<li>创建接口的实现类 CalImpl。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.utils.impl;
 
<span class="hljs-keyword">import</span> com.southwind.utils.Cal;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CalImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cal</span> </span>&#123;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        System.out.println(<span class="hljs-string">&quot;add方法的参数是[&quot;</span>+num1+<span class="hljs-string">&quot;,&quot;</span>+num2+<span class="hljs-string">&quot;]&quot;</span>);
        <span class="hljs-keyword">int</span> result = num1+num2;
        System.out.println(<span class="hljs-string">&quot;add方法的结果是&quot;</span>+result);
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sub</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        System.out.println(<span class="hljs-string">&quot;sub方法的参数是[&quot;</span>+num1+<span class="hljs-string">&quot;,&quot;</span>+num2+<span class="hljs-string">&quot;]&quot;</span>);
        <span class="hljs-keyword">int</span> result = num1-num2;
        System.out.println(<span class="hljs-string">&quot;sub方法的结果是&quot;</span>+result);
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">mul</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        System.out.println(<span class="hljs-string">&quot;mul方法的参数是[&quot;</span>+num1+<span class="hljs-string">&quot;,&quot;</span>+num2+<span class="hljs-string">&quot;]&quot;</span>);
        <span class="hljs-keyword">int</span> result = num1*num2;
        System.out.println(<span class="hljs-string">&quot;mul方法的结果是&quot;</span>+result);
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">div</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        System.out.println(<span class="hljs-string">&quot;div方法的参数是[&quot;</span>+num1+<span class="hljs-string">&quot;,&quot;</span>+num2+<span class="hljs-string">&quot;]&quot;</span>);
        <span class="hljs-keyword">int</span> result = num1/num2;
        System.out.println(<span class="hljs-string">&quot;div方法的结果是&quot;</span>+result);
        <span class="hljs-keyword">return</span> result;
    &#125;
&#125;</code></pre>

<p>上述代码中，日志信息和业务逻辑的耦合性很高，不利于系统的维护，使用 AOP 可以进行优化，如何来实现 AOP？使用动态代理的方式来实现。</p>
<p>给业务代码找一个代理，打印日志信息的工作交个代理来做，这样的话业务代码就只需要关注自身的业务即可。</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.utils;
 
<span class="hljs-keyword">import</span> java.lang.reflect.InvocationHandler;
<span class="hljs-keyword">import</span> java.lang.reflect.Method;
<span class="hljs-keyword">import</span> java.lang.reflect.Proxy;
<span class="hljs-keyword">import</span> java.util.Arrays;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyInvocationHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvocationHandler</span> </span>&#123;
    <span class="hljs-comment">//接收委托对象</span>
    <span class="hljs-keyword">private</span> Object object = <span class="hljs-keyword">null</span>;
 
    <span class="hljs-comment">//返回代理对象</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">bind</span><span class="hljs-params">(Object object)</span></span>&#123;
        <span class="hljs-keyword">this</span>.object = object;
        <span class="hljs-keyword">return</span> Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),<span class="hljs-keyword">this</span>);
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">invoke</span><span class="hljs-params">(Object proxy, Method method, Object[] args)</span> <span class="hljs-keyword">throws</span> Throwable </span>&#123;
        System.out.println(method.getName()+<span class="hljs-string">&quot;方法的参数是：&quot;</span>+ Arrays.toString(args));
        Object result = method.invoke(<span class="hljs-keyword">this</span>.object,args);
        System.out.println(method.getName()+<span class="hljs-string">&quot;的结果是&quot;</span>+result);
        <span class="hljs-keyword">return</span> result;
    &#125;
&#125;</code></pre>

<p>以上是通过动态代理实现 AOP 的过程，比较复杂，不好理解，Spring 框架对 AOP 进行了封装，使用 Spring 框架可以用面向对象的思想来实现 AOP。</p>
<p>Spring 框架中不需要创建 InvocationHandler，只需要创建一个切面对象，将所有的非业务代码在切面对象中完成即可，Spring 框架底层会自动根据切面类以及目标类生成一个代理对象。</p>
<p>LoggerAspect</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.aop;
 
<span class="hljs-keyword">import</span> org.aspectj.lang.JoinPoint;
<span class="hljs-keyword">import</span> org.aspectj.lang.annotation.*;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Component;
 
<span class="hljs-keyword">import</span> java.util.Arrays;
 
<span class="hljs-meta">@Aspect</span>
<span class="hljs-meta">@Component</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoggerAspect</span> </span>&#123;
 
    <span class="hljs-meta">@Before(value = &quot;execution(public int com.southwind.utils.impl.CalImpl.*(..))&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">before</span><span class="hljs-params">(JoinPoint joinPoint)</span></span>&#123;
        <span class="hljs-comment">//获取方法名</span>
        String name = joinPoint.getSignature().getName();
        <span class="hljs-comment">//获取参数</span>
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println(name+<span class="hljs-string">&quot;方法的参数是：&quot;</span>+ args);
    &#125;
 
    <span class="hljs-meta">@After(value = &quot;execution(public int com.southwind.utils.impl.CalImpl.*(..))&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">after</span><span class="hljs-params">(JoinPoint joinPoint)</span></span>&#123;
        <span class="hljs-comment">//获取方法名</span>
        String name = joinPoint.getSignature().getName();
        System.out.println(name+<span class="hljs-string">&quot;方法执行完毕&quot;</span>);
    &#125;
 
    <span class="hljs-meta">@AfterReturning(value = &quot;execution(public int com.southwind.utils.impl.CalImpl.*(..))&quot;,returning = &quot;result&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">afterReturning</span><span class="hljs-params">(JoinPoint joinPoint,Object result)</span></span>&#123;
        <span class="hljs-comment">//获取方法名</span>
        String name = joinPoint.getSignature().getName();
        System.out.println(name+<span class="hljs-string">&quot;方法的结果是&quot;</span>+result);
    &#125;
 
    <span class="hljs-meta">@AfterThrowing(value = &quot;execution(public int com.southwind.utils.impl.CalImpl.*(..))&quot;,throwing = &quot;exception&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">afterThrowing</span><span class="hljs-params">(JoinPoint joinPoint,Exception exception)</span></span>&#123;
        <span class="hljs-comment">//获取方法名</span>
        String name = joinPoint.getSignature().getName();
        System.out.println(name+<span class="hljs-string">&quot;方法抛出异常：&quot;</span>+exception);
    &#125;
 
&#125;</code></pre>

<p>LoggerAspect 类定义处添加的两个注解：</p>
<ul>
<li><code>@Aspect</code>：表示该类是切面类。</li>
<li><code>@Component</code>：将该类的对象注入到 IoC 容器。</li>
</ul>
<p>具体方法处添加的注解：</p>
<p><code>@Before</code>：表示方法执行的具体位置和时机。</p>
<p>CalImpl 也需要添加 <code>@Component</code>，交给 IoC 容器来管理。</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.utils.impl;
 
<span class="hljs-keyword">import</span> com.southwind.utils.Cal;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Component;
 
<span class="hljs-meta">@Component</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CalImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cal</span> </span>&#123;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        <span class="hljs-keyword">int</span> result = num1+num2;
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sub</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        <span class="hljs-keyword">int</span> result = num1-num2;
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">mul</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        <span class="hljs-keyword">int</span> result = num1*num2;
        <span class="hljs-keyword">return</span> result;
    &#125;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">div</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span> </span>&#123;
        <span class="hljs-keyword">int</span> result = num1/num2;
        <span class="hljs-keyword">return</span> result;
    &#125;
&#125;</code></pre>

<p>spring.xml 中配置 AOP。</p>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span> <span class="hljs-attr">xmlns:aop</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/aop&quot;</span> <span class="hljs-attr">xmlns:p</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/p&quot;</span> <span class="hljs-attr">xsi:schemalocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">&quot;</span>&gt;</span>
 
    <span class="hljs-comment">&lt;!-- 自动扫描 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">context:component-scan</span> <span class="hljs-attr">base-package</span>=<span class="hljs-string">&quot;com.southwind&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">context:component-scan</span>&gt;</span>
 
    <span class="hljs-comment">&lt;!-- 是Aspect注解生效，为目标类自动生成代理对象 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">aop:aspectj-autoproxy</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">aop:aspectj-autoproxy</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span></code></pre>

<p><code>context:component-scan</code> 将 <code>com.southwind</code> 包中的所有类进行扫描，如果该类同时添加了 <code>@Component</code>，则将该类扫描到 IoC 容器中，即 IoC 管理它的对象。</p>
<p><code>aop:aspectj-autoproxy</code> 让 Spring 框架结合切面类和目标类自动生成动态代理对象。</p>
<ul>
<li>切面：横切关注点被模块化的抽象对象。</li>
<li>通知：切面对象完成的工作。</li>
<li>目标：被通知的对象，即被横切的对象。</li>
<li>代理：切面、通知、目标混合之后的对象。</li>
<li>连接点：通知要插入业务代码的具体位置。</li>
<li>切点：AOP 通过切点定位到连接点。&lt;/long,&gt;&lt;/long,&gt;&lt;/long,&gt;&lt;/long,&gt;</element></element>&lt;/string,&gt;&lt;/string,object&gt;</li>
</ul>

    </div>
     
    <div class="post-footer__meta"><p>更新于 2022-04-09</p></div> 
    <div class="post-entry__tags"><a href="/tags/Spring/" class="post-tags__link button"># Spring</a></div> 
</article>


    <div class="nav">
        <div class="nav__prev">
            
                <a href="/2022/04/09/SpringMVC/" class="nav__link">
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M589.088 790.624L310.464 512l278.624-278.624 45.248 45.248L400.96 512l233.376 233.376z" fill="#808080"></path></svg>
                    </div>
                    <div>
                        <div class="nav__label">
                            <!-- Previous Post -->
                            上一页
                        </div>
                        <div class="nav__title">
                            Spring MVC
                        </div>
                    </div>
                </a>
            
        </div>
        <div class="nav__next">
            
                <a href="/2022/04/06/%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F1.0/" class="nav__link">
                    <div>
                        <div class="nav__label">
                            <!-- Next Post -->
                            下一页
                        </div>
                        <div class="nav__title">
                            Vue2+ElementUI后台管理系统
                        </div>
                    </div>
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M434.944 790.624l-45.248-45.248L623.04 512l-233.376-233.376 45.248-45.248L713.568 512z" fill="#808080"></path></svg>
                    </div>
                </a>
            
        </div>
    </div>



    <div class="post__comments content-card" id="comment">
        
    <h4>评论</h4>
    
    
    
    <div id="valine_container" class="valine_thread"></div>

    
    
    
    
    
    
    
    


    </div>



</main>

            <footer class="footer" style="font-size: 10px;">
     
    <a href="#" class="button" id="b2t" aria-label="回到顶部" title="回到顶部">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="32" height="32">
            <path d="M233.376 722.752L278.624 768 512 534.624 745.376 768l45.248-45.248L512 444.128zM192 352h640V288H192z" fill="currentColor"></path>
        </svg>
    </a>

    


    
    
    
        <span id="busuanzi_container_site_uv" hidden>
            <span>游客:</span>
            <span id="busuanzi_value_site_uv"></span>
            <span></span>
            
                <span> </span>
            
        </span>
    
    
        <span id="busuanzi_container_site_pv" hidden>
            <span>次数:</span>
            <span id="busuanzi_value_site_pv"></span>
            <span></span>
            
        </span>
    
 
 

 
    
    
    <p>
        <!-- Powered by <a href="https://hexo.io" target="_blank">Hexo</a> | Theme - <a href="https://github.com/ChrAlpha/hexo-theme-cards" target="_blank">Cards</a> -->
        <span style="color: black;">作者：张程</span>
    </p>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
    </script>
    <script>
        var a_idx = 0;
            jQuery(document).ready(function($) {
                $("body").click(function(e) {
                    var a = new Array("会当凌绝顶，一览众山小", "春蚕到死丝方尽，蜡炬成灰泪始干", "夕阳无限好，只是近黄昏",
                     "位卑未敢忘忧国", "纸上得来终觉浅，绝知此事要躬行", "人生自古谁无死，留取丹心照汗青", "山重水复疑无路，柳暗花明又一村" ,
                     "小荷才露尖尖角，早有蜻蜓立上头", "床前明月光，疑是地上霜", "春色满园关不住，一枝红杏出墙来", 
                     "山际见来烟，竹中窥落日", "道狭草木长，夕露沾我衣","天长地久有时尽，此恨绵绵无绝期");
                    var color = new Array("#7B7B7B", "#CE0000", "#FF0080","#E800E8","#921AFF","#2828FF",
                    "#0072E3","#00CACA","#02DF82","#00DB00","#8CEA00","#E1E100","#EAC100","#F75000"
                    ,"#B87070","#AFAF61","#6FB7B7","#9999CC","#B766AD");
                    var $i = $("<a href='#' style='text-decoration:none'/>").text(a[a_idx]);
                    a_idx = (a_idx + 1) % a.length;
                    var x = e.pageX,
                        y = e.pageY;
                    $i.css({
                        "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
                        "top": y - 20,
                        "left": x,
                        "position": "absolute",
                        "font-weight": "bold",
                        "color": color[Math.floor(Math.random()*color.length)]
                    });
                    $("body").append($i);
                    $i.animate({
                            "top": y - 180,
                            "opacity": 0
                        },
                        1500,
                        function() {
                            $i.remove();
                        });
                });
            });
        </script>
    <script>
        !function() {
            function o(w, v, i) {
                return w.getAttribute(v) || i
            }
            function j(i) {
                return document.getElementsByTagName(i)
            }
            function l() {
                var i = j("script"),
                w = i.length,
                v = i[w - 1];
                return {
                    l: w,
                    z: o(v, "zIndex", -1),
                    o: o(v, "opacity", 0.5),
                    c: o(v, "color", "0,0,0"),
                    n: o(v, "count", 99)
                }
            }
            function k() {
                r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
                n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
            }
            function b() {
                e.clearRect(0, 0, r, n);
                var w = [f].concat(t);
                var x, v, A, B, z, y;
                t.forEach(function(i) {
                    i.x += i.xa,
                    i.y += i.ya,
                    i.xa *= i.x > r || i.x < 0 ? -1 : 1,
                    i.ya *= i.y > n || i.y < 0 ? -1 : 1,
                    e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1);
                    for (v = 0; v < w.length; v++) {
                        x = w[v];
                        if (i !== x && null !== x.x && null !== x.y) {
                            B = i.x - x.x,
                            z = i.y - x.y,
                            y = B * B + z * z;
                            y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke())
                        }
                    }
                    w.splice(w.indexOf(i), 1)
                }),
                m(b)
            }
            var u = document.createElement("canvas"),
            s = l(),
            c = "c_n" + s.l,
            e = u.getContext("2d"),
            r,
            n,
            m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
            function(i) {
                window.setTimeout(i, 1000 / 45)
            },
            a = Math.random,
            f = {
                x: null,
                y: null,
                max: 20000
            };
            u.id = c;
            u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
            j("body")[0].appendChild(u);
            k(),
            window.onresize = k;
            window.onmousemove = function(i) {
                i = i || window.event,
                f.x = i.clientX,
                f.y = i.clientY
            },
            window.onmouseout = function() {
                f.x = null,
                f.y = null
            };
            for (var t = [], p = 0; s.n > p; p++) {
                var h = a() * r,
                g = a() * n,
                q = 2 * a() - 1,
                d = 2 * a() - 1;
                t.push({
                    x: h,
                    y: g,
                    xa: q,
                    ya: d,
                    max: 6000
                })
            }
            setTimeout(function() {
                b()
            }, 100)
    } ();
    </script>
</footer>

        </div>
        
    <script defer src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.1.0/dist/lazyload.min.js"></script>
    <script>
        window.lazyLoadOptions = {
            elements_selector: ".lazy",
            threshold: 0
        };
    </script>
 

 

 

 

 



 



 


    
 


    
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>

    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.css">

    
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.js"></script>

    <script>
        let lazyloadT = Boolean('true'),
            auto_fancybox = Boolean('false')
        if (auto_fancybox) {
            $(".post__content").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        } else {
            $(".post__content").find("fancybox").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        }
    </script>
 

 

 

 

 


    

    
    
    
    <script>
        function loadComment() {
            let e;
            (e = document.createElement("script")).src = 'https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js',
            document.body.appendChild(e);
            e.onload = () => {
                var valineConfig = {"appId":"c21JqSBfScFdueO44Scwp9Ba-gzGzoHsz","appKey":"apETP0QIekHzRXjTHvOnrQmS","placeholder":null,"path":null,"avatar":"retro","meta":["nick","mail","link"],"pageSize":null,"lang":null,"visitor":null,"highlight":null,"avatarForce":null,"recordIP":null,"serverURLs":null,"enableQQ":true,"requiredFields":["nick","mail"],"emojiCDN":null,"emojiMaps":null};
                valineConfig.el = '#valine_container';
                for (var i in valineConfig) {
                    if (valineConfig[i] === null) delete valineConfig[i];
                }
                new Valine(valineConfig);
            };
        }
    
        var runningOnBrowser = typeof window !== "undefined";
        var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent);
        var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
    
        setTimeout(function () {
            if (!isBot && supportsIntersectionObserver) {
                var comment_observer = new IntersectionObserver(function(entries) {
                    if (entries[0].isIntersecting) {
                        loadComment();
                        comment_observer.disconnect();
                    }
                }, { threshold: [0] });
                comment_observer.observe(document.getElementById('comment'));
            } else {
                loadComment();
            }
        }, 1);
    </script>


    
    
    
    
    

    
    
    
    
    

    
    
    



    </body>
</html>
